/*
 * スプライトテスト
 */
#define ASL_USE_MACRO

#include	<system.h>
#include	<v93.h>
#include	<nt.h>
#include	<farl.h>
#include	<asl.h>
#include	<agl.h>
#include	<common.h>
#include	<libm.h>
#include	<pio.h>

#define	Sin8(angle)	SinTable8[(angle) & 0xff]
#define	Cos8(angle)	SinTable8[((angle) & 0xff)+64]
#define	MAXCHAR		256
#define	OX			128
#define	OY			120

int	charnumber;		// スプライト登録数

ASLSct			sct;
ASLSource		src[MAXCHAR];
unsigned short  buf[163840];
unsigned short	colortable[512];

// Sin,Cosテーブル
int SinTable8[256+64] = {
	    0,   6,  13,  19,  25,  31,  38,  44,
	   50,  56,  62,  68,  74,  80,  86,  92,
	   98, 104, 109, 115, 121, 126, 132, 137,
	  142, 147, 152, 157, 162, 167, 172, 177,
	  181, 185, 190, 194, 198, 202, 206, 209,
	  213, 216, 220, 223, 226, 229, 231, 234,
	  237, 239, 241, 243, 245, 247, 248, 250,
	  251, 252, 253, 254, 255, 255, 256, 256,

/* _CosTable8 */
	  256, 256, 256, 255, 255, 254, 253, 252,
	  251, 250, 248, 247, 245, 243, 241, 239,
	  237, 234, 231, 229, 226, 223, 220, 216,
	  213, 209, 206, 202, 198, 194, 190, 185,
	  181, 177, 172, 167, 162, 157, 152, 147,
	  142, 137, 132, 126, 121, 115, 109, 104,
	   98,  92,  86,  80,  74,  68,  62,  56,
	   50,  44,  38,  31,  25,  19,  13,   6,

	    0,  -6, -13, -19, -25, -31, -38, -44,
	  -50, -56, -62, -68, -74, -80, -86, -92,
	  -98,-104,-109,-115,-121,-126,-132,-137,
	 -142,-147,-152,-157,-162,-167,-172,-177,
	 -181,-185,-190,-194,-198,-202,-206,-209,
	 -213,-216,-220,-223,-226,-229,-231,-234,
	 -237,-239,-241,-243,-245,-247,-248,-250,
	 -251,-252,-253,-254,-255,-255,-256,-256,

	 -256,-256,-256,-255,-255,-254,-253,-252,
	 -251,-250,-248,-247,-245,-243,-241,-239,
	 -237,-234,-231,-229,-226,-223,-220,-216,
	 -213,-209,-206,-202,-198,-194,-190,-185,
	 -181,-177,-172,-167,-162,-157,-152,-147,
	 -142,-137,-132,-126,-121,-115,-109,-104,
	  -98, -92, -86, -80, -74, -68, -62, -56,
	  -50, -44, -38, -31, -25, -19, -13,  -6,

	    0,   6,  13,  19,  25,  31,  38,  44,
	   50,  56,  62,  68,  74,  80,  86,  92,
	   98, 104, 109, 115, 121, 126, 132, 137,
	  142, 147, 152, 157, 162, 167, 172, 177,
	  181, 185, 190, 194, 198, 202, 206, 209,
	  213, 216, 220, 223, 226, 229, 231, 234,
	  237, 239, 241, 243, 245, 247, 248, 250,
	  251, 252, 253, 254, 255, 255, 256, 256
	};

int main (void);
void AicLoad (unsigned short bank, unsigned char *filename);
void SrcSet (unsigned short bank, int xsize, int ysize, int xnum, int ynum);
void AcdLoad(unsigned char *filename);
void InitSystem (void);
void InitScreen (void);
void SprRotZoomPut (int x, int y, int r, int z, int pat);
void DspWait (void);
void kingload(int bgnum, unsigned char *filename);

/*
 * メイン
 */
int
main()
	{
	int	i,j;
	int	head,deg,rot,zoom;
	int	xx,yy;

	// 初期化
	InitSystem();
	InitScreen();
	FX73init();
	FX73_cmap_i3c6();
	FarlInit();

	FarlSetPEICMaskReg(FARL_ICMASK_I3C6);		// I3C6 mode
	FarlSetTEControlReg(FARL_TE_ICM);

	KINGScreen(0);								// 画面モード16m色
	KINGDispOff();								// HuC6272 表示オフ
	KINGCylinder(KING_BG0,1);					// 茶筒モード
	KINGChangeSize0(DISP_NORMAL);				// 画面幅設定
	dispoff(bg | spr | rain | bg1 | bg2 | bg3);	// 他画面オフ
	dispon(bg | spr | bg0);						// 画面ON
	KINGCls(KING_BG0);							// 画面消去
	KINGDispOff();								// HuC6272 表示オン

	// スプライトの読み込みと登録
	charnumber = 0;
	AicLoad(0,"STEST.AIC");
	SrcSet(0,64,64,4,4);

	// パレットデータの読み込み
	AcdLoad("STEST.ACD");
	write_pallet_datas(0,colortable,512);

	// BG DATA READ
	kingload(KING_BG0,"STEST.BIN");

	KINGDispOn();								// HuC6272 表示オン

	// スプライトが表示される領域の設定
	ASLSetSpriteWindow( 0, 0, 255, 239 );

	head = 0;
	rot = 0;
	zoom = 0;

	get_pad();
	// メインループ
	while(1)
		{
		get_pad();
		if ( pad00.KD_TRG & KP_run )
			{
			while(1)
				{
				get_pad();
				if ( pad00.KD_TRG & KP_run ) break;
				}
			}

		// 拡大率
		zoom++;
		if ( zoom > 255 ) zoom -= 256;
		// 回転角
		rot += 10;
		if ( rot > 3599 ) rot -= 3600;
		// 先頭の位置
		head++;
		if ( head > 255 ) head -= 256;

		// スプライト表示
		for ( i = 0 ; i < 8 ; i++ )
			{
			deg = head + i * 32;
			xx = Sin8(deg%256) / 3 + OX;
			yy = Cos8(deg%256) / 3 + OY;
			SprRotZoomPut(xx, yy, rot, Sin8(zoom) + 5, i);
			}
		DspWait();
		}
	return	0;
	}

/*
 * AICファイルの読み込み
 */
void
AicLoad(unsigned short bank, unsigned char *filename)
	{
	int	fp, i, num;
	int	x,y;

	pio_putstr( "Sprite data loading..." );

	// 読み込み
	fp = pio_fopen(filename, "rb" );
	if ( fp == -1 )
		{
		pio_putstr( "\nCannot open AIC file.\n" );
		return;
		}
	i = pio_fread( fp, 4, (char *)( &num ) );
	if ( i < 4 )
		{
		pio_putstr( "\nAIC file read error.\n" );
		return;
		}
	i = pio_fread( fp, num, (char *)buf );
	if ( i < num )
		{
		pio_putstr( "\nAIC file read error.\n" );
		return;
		}
	FarlSetPETextureReg(bank);
	for ( i = 0; i < ( num / 2 ); i++ )
		{
		FarlWriteFifoH( buf[i] );
		}
	pio_putstr( "done.\n" );
	return;
	}

/*
 * パターン情報セット
 */
void
SrcSet(unsigned short bank, int xsize, int ysize, int xnum, int ynum)
	{
	int	i,j,n;

	for ( i = 0 ; i < ynum ; i++ )
		{
		for ( j = 0 ; j < xnum ; j++ )
			{
			src[charnumber].bank   = bank;
			src[charnumber].x_pos  = j*xsize;
			src[charnumber].y_pos  = i*ysize;
			src[charnumber].x_size = xsize;
			src[charnumber].y_size = ysize;
			src[charnumber].x_hot  = xsize/2;
			src[charnumber].y_hot  = ysize/2;
			charnumber++;
			}
		}
	}

/*
 * ACDファイルの読み込み
 */
void
AcdLoad(unsigned char *filename)
	{
	int	fp;

	pio_putstr( "palette data loading..." );

	// 読み込み
	fp = pio_fopen(filename, "rb" );
	if ( fp == -1 )
		{
		pio_putstr( "\nCannot open ACD file.\n" );
		return;
		}
	// ヘッダを飛ばす(64 + 40byteのACDの場合)
	pio_fread( fp, 104, (unsigned char *)colortable );

	// パレットデータ読み込み
	pio_fread( fp, 1024, (unsigned char *)colortable );

	pio_putstr( "done.\n" );
	return;
	}

/*
 * システム初期化
 */
void
InitSystem()
	{
	irq_disable();
	cache_clear();
	cache_enable();
    set_irq_mask(
		BIT_IRQM_SIO | 
		BIT_IRQM_7A | 
		BIT_IRQM_7B |
		BIT_IRQM_KING |
		BIT_IRQM_KP |
		BIT_IRQM_EXT |
		BIT_IRQM_TMI |
		BIT_IRQM_AERR |
		0
		);

	set_irq_prio(IRQ_PRIOA, IRQ_KP);
	set_irq_vector(&int_pad, IRQ_LEVELA);

    reset_irq_mask(
//			BIT_IRQM_SIO | 
//			BIT_IRQM_7A | 
//			BIT_IRQM_7B |
//			BIT_IRQM_KING |
			BIT_IRQM_KP |
//			BIT_IRQM_EXT |
//			BIT_IRQM_TMI |
//			BIT_IRQM_AERR |
			0
		);

	set_irq_level(0x0007);
	irq_enable();
	init_get_pad();
	get_pad();
	}

/*
 * 画面初期化
 */
void
InitScreen()
	{
	int i;

	init_nt();
	init_70();
	dispon(bg | spr | bg0 | bg1 | bg2 | bg3 | rain );
	dispoff( /*bg | spr |*/ bg0 | bg1 | bg2 | bg3 | rain );
	set_nt_mode(interlace | inter_sync | mode_5M | mode_sp256 | mode_bg256);

	cel_off(bg);
	cel_off(spr);
	cel_off(bg0);
	cel_off(bg1);
	cel_off(bg2);
	cel_off(bg3);
	cel_off(rain);
	}

/*
 * スプライト拡大縮小回転表示
 */
void
SprRotZoomPut(int x,int y,int r,int z,int pat)
	{
	ASLMakeZoomRotateSprite( &src[pat], x, y, r, z, &sct );
	ASLSetSpriteTable( 15, 0, 1, &sct );
	ASLExecuteSprite( 15, 0, 1);
	}

/*
 * 描画後処理
 */
void
DspWait()
	{
	ASLSync();
	FarlSwapWindow();
	ASLWaitForSwap();
	}

/*
 * KINGに描画
 */
void
kingload(int bgnum, unsigned char *filename)
	{
	int	fh;

	// ファイル読込
	pio_putstr( "BG data loading..." );
	if ( (fh = pio_fopen(filename, "rb")) == -1 )
		{
		pio_putstr("Can not open BG File.\n");
		return;
		}
	pio_fread(fh,122880,buf);
	pio_fclose(fh);
	KINGDispOff();
	KINGScreen(0);
	KINGCls(KING_BG0);
	KINGTrans(bgnum,buf,2);
	KINGDispOff();
	pio_putstr( "done.\n" );
	}

